/**
 * DAOMessage.java 25/04/2012
 */

package l3.info.projetJava.serveur;

import java.sql.Connection;
import java.util.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.log4j.Logger;

import l3.info.projetJava.client.Message;
import l3.info.projetJava.utilitaires.Configuration;
import l3.info.projetJava.utilitaires.DialogueBD;
import l3.info.projetJava.utilitaires.OperationDate;

/**
 * Permet d'accéder à la base de données ayant pour relation
 * un Message
 * @author Loïc Martinez
 * @version 1.0
 */

public class DAOMessage {
    /** Permet de charger la configuration de la base de données */
    private static Configuration conf = new Configuration(
            "configServer.properties");

    /** La connexion à la base de données */
    private static Connection conn = null;

    /** S'il y a encore des messages après l'OFFSET et LIMIT choisi */
    public static final int MESSAGES_YET = 1;

    /** Logger */
    private static Logger logger = Logger.getLogger(DAOMessage.class);
    
    /**
     * Constructeur par défaut
     */
    public DAOMessage() {
        conn = conn == null ? DialogueBD.connexionSQL(
                "jdbc:postgresql://localhost"
                        + (conf.valueOf("port").equals("") ? "" : ":")
                        + conf.valueOf("port")
                        + "/" + conf.valueOf("database"),
                        conf.valueOf("user"), conf.valueOf("password"))
                        : conn;
    }

    /**
     * Renvoie tous les messages pour un utilisateur
     * @param numUtilisateur, le numéro de l'utilisateur
     * @param message, le message à écrire
     * @param table, la table des messages
     */
    public void ecrireMessage(int numUtilisateur, String message,
            String table) {
        // idmessage, message, numutilisateur, datecreation
        try {

            // Création de la date actuelle
            Calendar now = Calendar.getInstance();

            // On construit la date à insérer dans la base de données
            String dateNow = now.get(Calendar.DAY_OF_MONTH) + "/"
                    + (now.get(Calendar.MONTH) +1) + "/" + now.get(Calendar.YEAR) 
                    + " " + now.get(Calendar.HOUR_OF_DAY) + ":"
                    + now.get(Calendar.MINUTE)
                    + ":" + now.get(Calendar.SECOND);

            // Pour faire le Insert Into du message, aller récupérer
            // le nombre de messages total puis faire +1
            // pour le nouvel IdMessage
            int numMessage = DialogueBD.countSQL(conn, table,
                    "idmessage") + 1;

            message = message.replaceAll("'", "''");

            // On insère le message dans la base de données
            DialogueBD.insertInto(conn, table, numMessage + ", " +"'"
                    + message + "' " + ", " + numUtilisateur + ", "
                    + "'" + dateNow + "'");

        } catch (SQLException ex) {
            // Erreur SQL DaoMessage
            logger.error("DAOMessage.ecrireMessage() : SQLException");
        }
    }

    /**
     * Renvoie tous les messages pour un utilisateur
     * @param numUtilisateur, le numéro de l'utilisateur
     * @param table, la table des messages
     * @return tous les messages contenus dans une List
     */
    public List<Message> getMessages(int aPartir, int nbMessages, int myId,
            String table) {

        List<Message> messages = new ArrayList<Message>();

        try {

            String requete = "SELECT message, heureCreation "
                    + "FROM " + table + " "
                    + "WHERE numUtilisateur = " + myId + " "
                    + "ORDER BY heureCreation DESC "
                    + "LIMIT " + nbMessages + " OFFSET " + aPartir + ";";

            // Exécution de la requête
            Statement state = conn.createStatement();
            ResultSet result = state.executeQuery(requete);

            // Un résultat trouvé
            while (result.next()) {
                // Date à mettre en forme
                String date = result.getTimestamp("heureCreation").toString();
                char[] dateForme = new char[21];

                dateForme[0] = date.charAt(8);
                dateForme[1] = date.charAt(9);
                dateForme[2] = '/';
                dateForme[3] = date.charAt(5);
                dateForme[4] = date.charAt(6);
                dateForme[5] = '/';
                dateForme[6] = date.charAt(0);
                dateForme[7] = date.charAt(1);
                dateForme[8] = date.charAt(2);
                dateForme[9] = date.charAt(3);
                dateForme[10] = ' ';
                dateForme[11] = 'à';
                dateForme[12] = ' ';
                dateForme[13] = date.charAt(11);
                dateForme[14] = date.charAt(12);
                dateForme[15] = date.charAt(13);
                dateForme[16] = date.charAt(14);
                dateForme[17] = date.charAt(15);
                dateForme[18] = date.charAt(16);
                dateForme[19] = date.charAt(17);
                dateForme[20] = date.charAt(18);

                date = new String(dateForme);

                messages.add(new Message(
                        result.getString("message").replaceAll("''", "'"),
                        date));
            }

            result.close();
            state.close();

            return messages;

        } catch (SQLException ex) {
            logger.error("DAOMessage.getMessages() : SQLException");
            return null;
        }
    }

    /**
     * Renvoie tous les messages pour un utilisateur
     * @param numUtilisateur, le numéro de l'utilisateur
     * @param table, la table des messages
     * @return tous les messages contenus dans une List
     */
    public List<Message> getMessages(int aPartir, int nbMessages, int myId,
            String table, String date1, String date2) {

        List<Message> messages = new ArrayList<Message>();

        // +1 jour pour date2
        // pour gérer les <= et >= des dates
        String myDate1 = date1;
        String myDate2 = date2;

        myDate2 = OperationDate.add(date2, +1);

        try {

            // Exécution de la requête
            Statement state;
            String requete = "";

            if (myDate1 != null && myDate2 == null) {
                requete = "SELECT message, heureCreation "
                        + "FROM " + table + " "
                        + "WHERE numUtilisateur = " + myId + " "
                        + "AND heureCreation > "
                        + "'" + myDate1 + "' "
                        + "ORDER BY heureCreation DESC "
                        + "LIMIT " + nbMessages + " OFFSET " + aPartir + ";";
            } else if (myDate1 == null && myDate2 != null) {
                requete = "SELECT message, heureCreation "
                        + "FROM " + table + " "
                        + "WHERE numUtilisateur = " + myId + " "
                        + "AND heureCreation < '" + myDate2 + "' "
                        + "ORDER BY heureCreation DESC "
                        + "LIMIT " + nbMessages + " OFFSET " + aPartir + ";";
            } else { // myDate1 != null && myDate2 != null
                requete = "SELECT message, heureCreation "
                        + "FROM " + table + " "
                        + "WHERE numUtilisateur = " + myId + " "
                        + "AND heureCreation BETWEEN "
                        + "'" + myDate1 + "' AND '" + myDate2 + "' "
                        + "ORDER BY heureCreation DESC "
                        + "LIMIT " + nbMessages + " OFFSET " + aPartir + ";";
            }

            // Exécution de la requête
            state = conn.createStatement();
            ResultSet result = state.executeQuery(requete);

            // Un résultat trouvé
            while (result.next()) {
                // Date à mettre en forme
                String date = result.getTimestamp("heureCreation").toString();
                char[] dateForme = new char[21];

                dateForme[0] = date.charAt(8);
                dateForme[1] = date.charAt(9);
                dateForme[2] = '/';
                dateForme[3] = date.charAt(5);
                dateForme[4] = date.charAt(6);
                dateForme[5] = '/';
                dateForme[6] = date.charAt(0);
                dateForme[7] = date.charAt(1);
                dateForme[8] = date.charAt(2);
                dateForme[9] = date.charAt(3);
                dateForme[10] = ' ';
                dateForme[11] = 'à';
                dateForme[12] = ' ';
                dateForme[13] = date.charAt(11);
                dateForme[14] = date.charAt(12);
                dateForme[15] = date.charAt(13);
                dateForme[16] = date.charAt(14);
                dateForme[17] = date.charAt(15);
                dateForme[18] = date.charAt(16);
                dateForme[19] = date.charAt(17);
                dateForme[20] = date.charAt(18);

                date = new String(dateForme);

                messages.add(new Message(
                        result.getString("message").replaceAll("''", "'"),
                        date));
            }

            result.close();
            state.close();

            return messages;

        } catch (SQLException ex) {
            logger.error("DAOMessage.getMessages() : SQLException");
            return null;
        }
    }

    /**
     * Permet de savoir combien il y aura de messages au prochain "suivant"
     * @param aPartir, le nombre de messages à partir de aPartir
     * @param nbMessages, le nombre de messages à voir
     * @param myId, mon id d'utilisateur
     * @param table, la table SQL
     * @return le nombre de messages restants
     */
    public int getNumberProchainsMessages(
            int aPartir, int nbMessages, int myId, String table) {

        try {
            // Exécution de la requête
            Statement state;

            String requete = "SELECT idmessage "
                    + "FROM " + table + " "
                    + "WHERE numUtilisateur = " + myId + " "
                    + "LIMIT " + nbMessages + " OFFSET " + aPartir
                    + ";";

            state = conn.createStatement();
            state.execute(requete);

            ResultSet result = state.executeQuery(requete);

            int res = 0;

            // On aura au moins un message
            if (result.next()) {
                res++;
            }

            result.close();
            state.close();

            return res;

        } catch (SQLException ex) {
            logger.error("DAOMessage.getNumberProchainsMessages() : SQLException");
            return -1;
        }
    }

    /**
     * Permet de savoir combien il y aura de messages au prochain "suivant"
     * @param aPartir, le nombre de messages à partir de aPartir
     * @param nbMessages, le nombre de messages à voir
     * @param myId, mon id d'utilisateur
     * @param table, la table SQL
     * @return le nombre de messages restants
     */
    public int getNumberProchainsMessages(
            int aPartir, int nbMessages, int myId, String table,
            String date1, String date2) {

        // +1 jour pour date2 pour gérer les <= et >= des dates
        String myDate1 = date1;
        String myDate2 = date2;

        myDate2 = OperationDate.add(date2, +1);

        try {

            // Exécution de la requête
            Statement state;
            String requete = "";

            if (myDate1 != null && myDate2 == null) {
                requete = "SELECT idmessage "
                        + "FROM " + table + " "
                        + "WHERE numUtilisateur = " + myId + " "
                        + "AND heureCreation > "
                        + "'" + myDate1 + "' "
                        + "LIMIT " + nbMessages + " OFFSET " + aPartir
                        + ";";
            } else if (myDate1 == null && myDate2 != null) {
                requete =  "SELECT idmessage "
                        + "FROM " + table + " "
                        + "WHERE numUtilisateur = " + myId + " "
                        + "AND heureCreation < '" + myDate2 + "' "
                        + "LIMIT " + nbMessages + " OFFSET " + aPartir
                        + ";";
            } else { // myDate1 != null && myDate2 != null
                requete = "SELECT idmessage "
                        + "FROM " + table + " "
                        + "WHERE numUtilisateur = " + myId + " "
                        + "AND heureCreation BETWEEN "
                        + "'" + myDate1 + "' AND '" + myDate2 + "' "
                        + "LIMIT " + nbMessages + " OFFSET " + aPartir
                        + ";";
            }

            state = conn.createStatement();
            state.execute(requete);

            ResultSet result = state.executeQuery(requete);

            int res = 0;

            // On aura au moins un message
            if (result.next()) {
                res++;
            }

            result.close();
            state.close();

            return res;

        } catch (SQLException ex) {
            logger.error("DAOMessage.getNumberProchainsMessages() : SQLException");
            return -1;
        }
    }
}
